package com.linktel.productionLine.EasyExcel.monthPlanning;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.linktel.productionLine.EasyExcel.monthPlanning.model.MonthlyPlanningUnionKey;
import com.linktel.productionLine.EasyExcel.monthPlanning.model.WriteMonthlyPlanning;
import com.linktel.productionLine.common.BaseContext;
import com.linktel.productionLine.common.ErrorCode;
import com.linktel.productionLine.dao.BaseStepDao;
import com.linktel.productionLine.dao.MonthlyPlanningDao;
import com.linktel.productionLine.dao.ProductionLineDao;
import com.linktel.productionLine.entity.dto.baseStep.BaseStepDTO;
import com.linktel.productionLine.entity.dto.monthlyPlanning.MonthlyPlanningNumberDTO;
import com.linktel.productionLine.entity.dto.productionLine.ProductionLineDTO;
import com.linktel.productionLine.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 上传excel文件，批量保存月度产能规划，创建easyExcel读的监听器
 *
 */
@Slf4j
public class MonthlyPlanningListener extends AnalysisEventListener<WriteMonthlyPlanning> {

    private MonthlyPlanningDao monthlyPlanningDao;
    private BaseStepDao baseStepDao;
    private ProductionLineDao productionLineDao;
    private Long currentUserId;
    private final List<WriteMonthlyPlanning> list = new ArrayList<>();
    private final List<MonthlyPlanningUnionKey> monthlyPlanningUnionKeys = new ArrayList<>();
    private List<String> productionLineCodeList;
    private List<String> baseCodeList;
    private Integer loadingNumber = 0;
    private Integer repeatedNumber = 0;
    private Integer unusefulNumber = 0;
    private Integer editNumber = 0;
    private Integer increasedNumber = 0;

    public MonthlyPlanningListener(MonthlyPlanningDao monthlyPlanningDao, Long currentUserId, ProductionLineDao productionLineDao, BaseStepDao baseStepDao) {
        this.productionLineDao = productionLineDao;
        this.baseStepDao = baseStepDao;
        this.currentUserId = currentUserId;
        this.monthlyPlanningDao = monthlyPlanningDao;
        this.productionLineCodeList = productionLineDao.listProductionLine(currentUserId).stream().map(ProductionLineDTO::getCode).collect(Collectors.toList());
        this.baseCodeList = baseStepDao.listBaseStep().stream().map(BaseStepDTO::getCode).collect(Collectors.toList());
    }

    @Override
    public void invoke(WriteMonthlyPlanning data, AnalysisContext context) {
        loadingNumber++;
        String productionLineCode = data.getProductionLineCode();
        String year = data.getYear();
        String month = data.getMonth();
        Integer planningNumber = data.getPlanningNumber();
        String keyStepCode = data.getKeyStepCode();
        MonthlyPlanningUnionKey monthlyPlanningUnionKey = new MonthlyPlanningUnionKey(productionLineCode, year, month, keyStepCode, planningNumber);
        if (StringUtils.isAnyBlank(productionLineCode, year, month)) {
            unusefulNumber++;
            log.info("{}, 传入的产线编码、年、月不能为空", data);
            return ;
        }
        if (!productionLineCodeList.contains(productionLineCode)) {
            unusefulNumber++;
            log.info("{}，该产线不存在在已有的产线中", data);
            return ;
        }
        if (keyStepCode != null && !baseCodeList.contains(keyStepCode)) {
            unusefulNumber++;
            log.info("{}, 关键工序不存在在已有的工序中", data);
            return ;
        }
//        List<Long> monthlyPlanningCapacityInfos = monthlyPlanningDao.getMonthlyPlanningCapacityInfo(productionLineCode, keyStepCode, year, month, currentUserId);
//        if (!CollectionUtils.isEmpty(monthlyPlanningCapacityInfos)) {
//            log.info("{}, 一条产线、一个关键工序，同一年，同一月只能有一条数据，不能重复添加", data);
//            return ;
//        }
//        String baseStepNameByCode = baseStepDao.getBaseStepNameByCode(keyStepCode);
//        data.setKeyStepName(baseStepNameByCode);
        if (planningNumber == null || monthlyPlanningUnionKeys.contains(monthlyPlanningUnionKey)) {
            repeatedNumber++;
            return ;
        }
        list.add(data);
        monthlyPlanningUnionKeys.add(monthlyPlanningUnionKey);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        BaseContext.setCurrentLog("");
        saveData();
    }

    private void saveData() {
        if (list.size() > 0) {
            List<WriteMonthlyPlanning> monthlyPlanningList = monthlyPlanningDao.listMonthlyPlanningDTO(currentUserId);
            Map<MonthlyPlanningUnionKey, Long> map = new HashMap<>();
            monthlyPlanningList.forEach(item -> {
                map.put(new MonthlyPlanningUnionKey(item.getProductionLineCode(), item.getYear(), item.getMonth(), item.getKeyStepCode(), item.getPlanningNumber()), item.getId());
            });
            list.forEach(item -> {
                MonthlyPlanningUnionKey monthlyPlanningUnionKey = new MonthlyPlanningUnionKey(item.getProductionLineCode(), item.getYear(), item.getMonth(), item.getKeyStepCode(), item.getPlanningNumber());
                if (map.containsKey(monthlyPlanningUnionKey)) {
                    item.setId(map.get(monthlyPlanningUnionKey));
                    editNumber++;
                } else {
                    increasedNumber++;
                }
            });
            monthlyPlanningDao.batchReplaceSave(list, currentUserId);
            BaseContext.setCurrentLog("加载到" + loadingNumber + "条数据，其中 "+ unusefulNumber +" 条不合法数据，" + repeatedNumber + "条重复数据；成功修改了" + editNumber + "条数据，新增了" + increasedNumber + "条数据。");
        } else {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "插入失败");
        }
    }

}
